package dao;

import java.util.HashMap;
import java.util.List;

import javax.persistence.EntityExistsException;
import javax.persistence.Query;
import javax.persistence.TransactionRequiredException;

import excepciones.DaoException;
import modelo.AreaTematica;
import modelo.Estado;
import modelo.Proyecto;
import modelo.Model;
import modelo.UnidadAcademica;
import modelo.Usuario;

public class ProyectoDao extends AbstractDao {
	
	
	/**
	* Class Constructor [Empty]
	*/
	public ProyectoDao()
	{
	   super();
	}
	
	/**
    * Class Constructor
    * @param model   The Usuario model to manage persistence for
    */
    public ProyectoDao(Proyecto ProyectoModel)
    {
      super(ProyectoModel);      
      this.model = (Proyecto) model;
    }

	@Override
	public Proyecto findById(Long id) throws DaoException {
		// TODO Auto-generated method stub
		try
	      {
	         model = (Proyecto) super.findById(Proyecto.class, id);
	      }
	      catch(Exception e)
	      {
	         e.printStackTrace();
	      }
	      
	      
	      return (Proyecto) model;
	}

	@Override
	public Model getModel() {
		// TODO Auto-generated method stub
		return (Proyecto) model;
	}
	
	public void createAccess() throws DaoException
	   {
	      startTxn();
	      try
	      {
	         entityManager.persist( model );
	         entityManager.getTransaction().commit();
	      }
	      catch(EntityExistsException e)
	      {
	         entityManager.getTransaction().rollback();
	         e.printStackTrace();
	         throw new DaoException("Create Failed: " + e.getMessage());
	      }
	      catch(IllegalArgumentException e)
	      {
	         entityManager.getTransaction().rollback();
	         e.printStackTrace();
	         throw new DaoException("Create Failed: " + e.getMessage());
	      }
	      catch(TransactionRequiredException e)
	      {
	         entityManager.getTransaction().rollback();
	         e.printStackTrace();
	         throw new DaoException("Create Failed: " + e.getMessage());
	      }
	   }

	public List<Proyecto> proyectosDeUsuario(Long id) {
		// TODO Auto-generated method stub
		return null;
	}

	public List<Proyecto> todosLosproyectosDeUsuario() {
		// TODO Auto-generated method stub
		
		 Query cons = entityManager.createQuery("SELECT p from Proyecto p");
		 List<Proyecto> proyectos = (List<Proyecto>) cons.getResultList();
		 
		return proyectos;
	}

	public  List <Proyecto> getProyectosDirector(Usuario usr) throws DaoException {
		
		try
	      {				         
	         List <Proyecto> proyectos = 
	        		 (List<Proyecto>) super.getEntityManager().
	               createQuery("Select p from Proyecto as p where p.perfil_director = ?1")
	                .setParameter(1, usr)
	                .getResultList();
	         //super.setModel( UsuarioModel );
	         return proyectos;	
	      }
	      catch(IllegalStateException e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	      catch(IllegalArgumentException e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	      catch(Exception e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	      
	      
	     	
		
	}

	public List<Proyecto> getProyectosIntegrante(Usuario usr) throws DaoException {
		try
	      {				         
	         List <Proyecto> proyectos = 
	        		 (List<Proyecto>) super.getEntityManager().
	               createQuery("Select p from Proyecto as p join p.integrantes as i where i = ?1")
	                .setParameter(1, usr)
	                .getResultList();
	         //super.setModel( UsuarioModel );
	         return proyectos;	
	      }
	      catch(IllegalStateException e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	      catch(IllegalArgumentException e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	      catch(Exception e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	}

	public List<Proyecto> getProyectosEvaluador(Usuario usr) throws DaoException {
		try
	      {				         
	         List <Proyecto> proyectos = 
	        		 (List<Proyecto>) super.getEntityManager().
	               createQuery("from Proyecto as p where p.perfil_evaluador = ?1")
	                .setParameter(1, usr)
	                .getResultList();
	         //super.setModel( UsuarioModel );
	         return proyectos;	
	      }
	      catch(IllegalStateException e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	      catch(IllegalArgumentException e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	      catch(Exception e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	}
	
	public HashMap<String, Long> estadisticaPorAreas(){
		HashMap<String, Long> result = new HashMap<String, Long>();
		
		List<Object[]> tuples = entityManager.createQuery("SELECT a, count(p) FROM Proyecto as p JOIN p.areas_tematicas as a GROUP BY a.id").getResultList();
			
			
			for (Object[] tuple: tuples) {
				AreaTematica a = (AreaTematica) tuple[0];
			    result.put(a.getNombre(), (Long) tuple[1]);
			    
			}
		
		return result;
	}

	public Long cantidadProyectos() {
		Long cantidad = (Long)entityManager.createQuery(
			    "SELECT count(*) as cant " +
			    "FROM Proyecto as p ").getSingleResult();				
		
		return cantidad;
	}

	public HashMap<String, Long> estadisticaPorUnidadesAcademicas() {
		HashMap<String, Long> result = new HashMap<String, Long>();
		
		List<Object[]> tuples = entityManager.createQuery("SELECT a, count(p) FROM Proyecto as p JOIN p.mis_unidades_academicas as a GROUP BY a.id").getResultList();
			
			
			for (Object[] tuple: tuples) {
				UnidadAcademica a = (UnidadAcademica) tuple[0];
			    result.put(a.getNombre(), (Long) tuple[1]);
			    
			}
		
		return result;
	}

	public List<Proyecto> getProyectosPorEstado( Estado unEstado) throws DaoException {
		try
	      {				         
	         List <Proyecto> proyectos = 
	        		 (List<Proyecto>) super.getEntityManager().
	               createQuery("from Proyecto as p where p.mi_estado = ?1 ")
	                .setParameter(1, unEstado)
	                .getResultList();
	         //super.setModel( UsuarioModel );
	         return proyectos;	
	      }
	      catch(IllegalStateException e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	      catch(IllegalArgumentException e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	      catch(Exception e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	}

	public List<AreaTematica> getAreasAgrupadas() throws DaoException {
		try
	      {				         
	         List <AreaTematica> proyectos = 
	        		 (List<AreaTematica>) super.getEntityManager().
	               createQuery("SELECT a, count(p) FROM Proyecto as p JOIN p.areas_tematicas as a GROUP BY a.id")
	                .getResultList();
	         //super.setModel( UsuarioModel );
	         return proyectos;	
	      }
	      catch(IllegalStateException e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	      catch(IllegalArgumentException e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	      catch(Exception e)
	      {
	         throw new DaoException("Find by Email Failed: " + e.getMessage());
	      }
	}
	
}
